home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 2
/
Atari Mega Archive CD - Volume 2.iso
/
minix
/
up1510b.tgz
/
up1510b
/
src
/
commands
/
btoa.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-07-23
|
28KB
|
1,115 lines
/* btoa - binary to ascii Authors: P. Rutter, J. Orost, & S. Parmark */
/*************************************************************************
Btoa is a filter which reads binary bytes from the input
file and generates printable ASCII characters on the output
file. It attaches a header and a checksum to the archive. It
can also reverse this, creating a binary file from the
archive.
Since last version of btoa/atob, several new features have
been added. The most obvious one is that atob has been
integrated with btoa. They are now the same program which is
called with different arguments. Another is the ability to
repair damaged archives.
The new version is compatible with the old version, that is,
it can still encode and decode old btoa files.
Btoa has an option to decode the archive, restoring the
binary bytes. It strips the input file until it finds a
valid header, and continues decoding until the end mark is
found. It recognices both old- and new-style headers, and
can decode both. It is possible to leave out the destination
name when decoding new-style archives, because the name is
stored in the header. Entering a name will override the
autonaming function.
It is possible to leave out the file names and redirect
stdin and stdout with '<' and '>' to the desired files. This
is to maintain compatibility with earlier versions of btoa.
Btoa now adds a single byte checksum to each row in the
archive. When an error is found, diagnosis automatically
starts and produces a diagnosis file which can be used to
extract the damaged part from an errorfree archive. The
extracted part can then be used to correct the damaged
archive. Btoa has options to perform the reparation
automatically. This is especially useful when downloading
data converted to text files, and occasionally finding that
an archive file of considerable size turns is corrupted.
FEATURES
Btoa encodes 4 binary bytes into 5 characters, expanding the
file by 25%. As a special case 4 zeroes will be encoded as
'z' and 4 spaces as 'y'. This makes it possible to compress
the archive a bit.
EXAMPLES
Below follows a description of a normal repair session.
Lines beginning with 'Local>' were typed on the computer to
which the file was downloaded. Accordingly, lines typed on
the connected computer will begin with 'Remote>'. Sending a
file to the other computer will be noted as 'transmit file'.
A normal repairing procedure is as follows: Local> btoa -a
file.btoa btoa: Bad checksum on line 2648. btoa: Starting
diagnosis. btoa: Diagnosis output to 'btoa.dia'. Local>
transmit btoa.dia
Remote> btoa -d file.btoa btoa: Repair output to 'btoa.rep'.
Remote> transmit btoa.rep
Local> btoa -a btoa.rep btoa: Repaired archive written to
'btoa.rdy'.
You can now erase file.btoa and decode btoa.rdy using 'btoa
-a btoa.rdy'.
*************************************************************************/
#include <sys/types.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#define MAXPERLINE 78
#define BUFSIZE 100
#define TRUE 1
#define FALSE 0
#define USE_MACROS TRUE
#define BYTE char
#define WORD short
#define LONG long
#define ENCODE(ch) ( (int) ((ch) + '!') )
#define DECODE(ch) ( (int) ((ch) - '!') )
struct Diagnosis {
LONG startpos, endpos; /* Line before and after erroneous area */
struct Diagnosis *next, *last;
};
extern char *malloc();
/* Following functions have been converted to macros: calcchecksum() */
#if LATTICE /* Prototypes for Lattice C */
void asciiout(int), exit(int),
intodiaglist(struct Diagnosis *, LONG, LONG),
outdiaglist(struct Diagnosis *, LONG *, LONG *), printhelp(void),
producediag(struct Diagnosis *, FILE *), wordout(LONG);
BYTE atob(FILE *), btoa(FILE *, BYTE *), copyfile(FILE *, FILE *, BYTE *),
decode_line(BYTE *, int), new_decodefile(FILE *, LONG *, LONG, int),
old_decodefile(FILE *, LONG *), performrepair(FILE *),
pro_repair(FILE *), readbuffer(BYTE *, BYTE *, FILE *),
*truncname(BYTE *);
int nextbyte(FILE *);
FILE *fopen_read(BYTE *), *fopen_write(BYTE *);
#if USE_MACROS
void calcchecksum(int);
#endif /* USE_MACROS */
#else /* !LATTICE */ /* For compilers which don't know about prototypes. */
void asciiout(), exit(), intodiaglist(), outdiaglist(),
printhelp(), producediag(), wordout();
BYTE atob(), btoa(), copyfile(), decode_line(), new_decodefile(),
old_decodefile(), performrepair(), pro_repair(), readbuffer(),
*truncname();
int nextbyte();
FILE *fopen_read(), *fopen_write();
#if USE_MACROS
void calcchecksum();
#endif /* USE_MACROS */
#endif /* LATTICE */
/* Chksum.h */
/* Calcchecksum() was converted to a macro for effectivity reasons. */
/* Don't (!!) give it an argument that has to be evaluated. This */
/* Is guaranteed to slow it down. */
/* Update file checksums. */
#define calcchecksum(ch) \
{ \
extern LONG Ceor, Csum, Crot; \
\
Ceor ^= ch; \
Csum += ch + 1; \
\
if (Crot & 0x80000000L) \
{ \
Crot <<= 1; \
Crot ++; \
} \
else \
Crot <<= 1; \
\
Crot += ch; \
}
/* Btoa.c */
/* Written by Paul Rutter, Joe Orost & Stefan Parmark. */
#ifdef AMIGA
#include <stdlib.h>
#include <string.h>
#endif /* AMIGA */
#define VERSION "5.2"
LONG Ceor, Csum, Crot; /* Checksums to verify archive validity. */
BYTE new_version, openoutput, buffer[BUFSIZE];
FILE *outfile;
void main(argc, argv)
int argc;
BYTE **argv;
{
register BYTE openinput, error, ch, a_to_b, diag, repair;
register BYTE *infilename, *text;
register FILE *infile;
extern BYTE new_version, openoutput;
extern FILE *outfile;
#ifdef AMIGA
extern int _bufsiz;
/* Change file buffer size. */
_bufsiz = 10240;
#endif /* AMIGA */
error = openinput = openoutput = a_to_b = diag = repair = FALSE;
new_version = TRUE;
infilename = NULL;
/* Scan for '-' options. The rest must be file names. */
while (!error && argc > 1 && *argv[1] == '-') {
text = &argv[1][1];
while (!error && (ch = *text++) != 0) {
switch (ch) {
case 'a': /* Activate atob. */
a_to_b = TRUE;
break;
case 'd': /* Extract missing part from
* undamaged archive. */
diag = TRUE;
break;
case 'h': /* Print help and abort execution. */
error = TRUE;
break;
case 'o': /* Use old btoa format. */
new_version = FALSE;
break;
case 'r': /* Repair damaged archive. */
repair = TRUE;
break;
default: error = TRUE;
}
}
argv++;
argc--;
}
if (argc > 3) error = TRUE;
if (error)
printhelp();
else {
/* If file name was given, try to open file. Otherwise use stdin. */
if (argc > 1) {
infilename = argv[1];
if ((infile = fopen_read(infilename)) == NULL)
error = TRUE;
else
openinput = TRUE;
} else
infile = stdin;
}
if (!error) {
/* If file name was given, try to open file. Otherwise use stdout. */
if (argc > 2 && !diag && !repair) {
if ((outfile = fopen_write(argv[2])) == NULL)
error = TRUE;
else
openoutput = TRUE;
} else
outfile = stdout;
}
if (!error) {
if (diag)
error = pro_repair(infile);
else if (repair)
error = performrepair(infile);
else if (a_to_b)
error = atob(infile);
else
error = btoa(infile, infilename);
}
/* Close all opened files. */
if (openinput) fclose(infile);
if (openoutput) fclose(outfile);
if (error) exit(1);
}
BYTE btoa(infile, infilename)
register FILE *infile;
register BYTE *infilename;
{
register LONG codeword, fil